package com.bjy.qa.agent.tools.resttemplate;

import com.bjy.qa.agent.tools.SpringTool;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

public class RestTemplateHelper {
    private static final Logger logger = LoggerFactory.getLogger(RestTemplateHelper.class);

    private static final RestTemplate restTemplate;

    static {
        restTemplate = SpringTool.getBean(RestTemplate.class);
    }

    /**
     * http get 请求
     * @param url url
     * @param headers head 参数
     * @param uriParams url 参数
     * @param responseType 响应类型
     * @return
     * @param <T>
     */
    public static <T> ResponseEntity<T> httpGet(String url, Map<String , String> headers, Map<String , String> uriParams, Class<T> responseType) {
        try {
            url = getHttpGetURL(url, uriParams); // 根据 url 参数，生成完整 url

            // 生成 HttpHeaders
            HttpHeaders httpHeaders = new HttpHeaders();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }

            HttpEntity requestEntity = new HttpEntity<>(httpHeaders); // 生成 HttpEntity

            ResponseEntity<T> result = restTemplate.exchange(url, HttpMethod.GET, requestEntity, responseType);
            return result;
        } catch (Exception e) { // 网络请求异常
            e.printStackTrace();
            logger.error("RestTemplateHelper 请求异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * http post 请求 - FORM
     * @param url url
     * @param headers head 参数
     * @param uriParams url 参数
     * @param bodyParams body 参数
     * @param responseType 响应类型
     * @return
     * @param <T>
     */
    public static <T> ResponseEntity<T> httpPostFormBody(String url, Map<String , String> headers, Map<String , String> uriParams, Map<String , Object> bodyParams, Class<T> responseType) {
        try {
            url = getHttpGetURL(url, uriParams); // 根据 url 参数，生成完整 url

            // 生成 HttpHeaders
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }

            // 生成 body
            MultiValueMap<String, Object> multiValueBodyParams = new LinkedMultiValueMap<>();
            for (Map.Entry<String, Object> entry: bodyParams.entrySet()) {
                multiValueBodyParams.add(entry.getKey(), entry.getValue());
            }

            HttpEntity requestEntity = new HttpEntity<>(multiValueBodyParams, httpHeaders); // 生成 HttpEntity

            ResponseEntity<T> result = restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType);
            return result;
        } catch (Exception e) { // 网络请求异常
            e.printStackTrace();
            logger.error("RestTemplateHelper 请求异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * http post 请求 - JSON
     * @param url url
     * @param headers head 参数
     * @param uriParams url 参数
     * @param bodyParams body 参数
     * @param responseType 响应类型
     * @return
     * @param <T>
     */
    public static <T> ResponseEntity<T> httpPostJsonBody(String url, Map<String , String> headers, Map<String , String> uriParams, Map<String , Object> bodyParams, Class<T> responseType) {
        try {
            url = getHttpGetURL(url, uriParams); // 根据 url 参数，生成完整 url

            // 生成 HttpHeaders
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpHeaders.add(entry.getKey(), entry.getValue());
            }

            HttpEntity requestEntity = new HttpEntity<>(bodyParams, httpHeaders); // 生成 HttpEntity

            ResponseEntity<T> result = restTemplate.exchange(url, HttpMethod.POST, requestEntity, responseType);
            return result;
        } catch (Exception e) { // 网络请求异常
            e.printStackTrace();
            logger.error("RestTemplateHelper 请求异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 生成 get 方法的请求 url
     * 例如：urr=http://www.baidu.com/aaa parameters=[param1=value1, param2=value2] 生成的 url 为：http://www.baidu.com/aaa?param1=value1&param2=value2
     * @param url 请求 url
     * @param parameters 请求参数
     * @return 生成的 url
     */
    private static String getHttpGetURL(String url, Map<String , String> parameters) {
        if ((parameters == null) || (StringUtils.isEmpty(url))) {
            return url;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(url);
        if (!StringUtils.endsWith(url, "?")) {
            sb.append("?");
        }
        for (Map.Entry<String, String> kvs : parameters.entrySet()) {
            String name = kvs.getKey();
            String value = encode((String) kvs.getValue());
            sb.append(name).append("=").append(value).append("&");
        }
        String result = sb.toString();
        if (result.endsWith("&")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    /**
     * 对传入的内容进行 url 编码
     * @param value 需要编码的内容
     * @return 编码后的内容
     */
    private static String encode(String value) {
        try {
            if (value != null)
                return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e.getMessage(), e);
        }
        return null;
    }
}
